Java Blog

Since I'm very lazy in sharing my thoughts, this blog may contain very few posts - so please be patient! :-)

Montag, Juli 21, 2008

Maven 2 "POM Inheritance" - Revisited

Ich habe die Lösung! Ein Kollege hat mich auf die Idee gebracht, doch nicht den How-Tos der ganzen Maven2-Büchern zu folgen :o) - also <version> und <groupId> aus dem Parent-POM in den Kind-POMs wieder zu verwenden.

Statt dessen trenne ich beide Versionierungen und definiere die Version des Parent-POM als konstant (z. B. "1") und hinterlege dort die eigentlichen Project-Artifact-Properties:

<project>
...
<groupId>test.group</groupId>
<artifactId>parent</artifactId>
<version>1</version>

<properties>
<project.artifact.groupId>test.group</project.artifact.groupId>
<project.artifact.version>1.0.0.2</project.artifact.version>
</properties>
...
</project>

In meinen Kind-POMs referenziere ich dann das Parent-POM mit dem <parent>-Tag und re-definiere aber <groupId> und <version> mit den im Parent-POM definierten Properties:

<project>
...
<parent>
<groupId>test.group</groupId>
<artifactId>parent</artifactId>
<version>1</version>
</parent>

<groupId>${project.artifact.groupId}</groupId>
<artifactId>child1</artifactId>
<version>${project.artifact.version}</version>
...
</project>

Dadurch habe ich zwar unterschiedliche Versionen des Parent-POM und des eigentlichen Projekts - muss aber trotzdem die Versionsnummer für ein neues Release meines Projekts nur an einer Stelle ändern - die Properties im Parent-POM.

Genau so, wie ich es haben wollte! Nur ein wenig anders... :o)

Labels: ,

Freitag, Juli 18, 2008

Maven 2 "POM Inheritance"

Ich beschäftige mich gerade mit Maven 2. In meiner Firma verwenden wir ein Maven 1 Buildsystem, das auch das Multiproject-Plug-In verwendet.

Die Projektstruktur sieht in etwa so aus:

ROOT/
project/
module-1/
project.properties
project.xml - <extend>../commons/project.xml</extend>
module-2/
project.properties
project.xml - <extend>../commons/project.xml</extend>
commons/
project.properties - definiert alle Dependency-Versionsnummern, aber auch
Version und Group-ID des gesamten Projekts
project.xml - definiert gemeinsame Dependencies
project.properties - Multi-Project-Konfigurations-Properties
project.xml - <extend>commons/project.xml</extend>

Das commons-Projekt enthält das "Parent-POM", welches sowohl die gemeinsamen Dependencies mit ihren Versionsnummern (ausgelagert in project.properties) als auch die Versionsnummer und Group-ID des gesamten Projekts - also die Vorgabe für alle Module - enthält.

Die Module selbst enthalten weder <groupId> noch <version>-Tags, sondern "erben" diese von dem commons/project.xml mittels <extend>-Tag ("POM Inheritance").

Damit werden Versionsnummer und Group-ID zentral über das commons-Projekt gesteuert und es muss bei einem neuen Release nur an dieser einen Stelle editiert werden.

Über die übergeordnete project.xml-Datei ist mittels multiproject-plugin ein Build des gesamten Projekt - also aller Module - möglich. In project.properties wird dabei mit Include- und Exclude-Patterns definiert, welche project.xml-Dateien der untergeordneten Module in den Mutiproject-Build einfließen sollen ("POM Aggregation").
Dabei wird z. B. das commons/project.xml exkludiert, da es ja nur das "Parent-POM" für alle anderen Module ist.

Mit Maven 2 ist alles ein wenig anders.

Es wird allerdings ebenfalls unterschieden in "POM Inheritance" und "POM Aggregation".

"POM Aggregation" ist einfach: das Top-Level-Projekt enthält in einer <modules>-Sektion alle Module, die gleichzeitig gebaut werden sollen - also voneinander abhängig sind.
Das war mit Maven 1 nur über ein zusätzliches Plug-In - maven-multiproject-plugin - möglich, während "POM Aggregation" bei Maven 2 nun integraler Bestandteil ist.

Mit "POM Inheritance", wie sie in Maven 2 implementiert ist, habe ich aber so meine Probleme.

Das "Parent POM" - in Maven 1 mittels <extend> als bloße Datei-Ressource definiert - wird nun über alle drei Projekt-Koordinaten referenziert: Group-ID, Artifact-ID und Version. Dafür darf dann in dem Kind-POM die Group-ID und die Version "fehlen" (siehe Beispiel).

<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>eu.zanner.test</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
</parent>
<artifactId>test-module</artifactId>
...
</project>

"Fehlen" tun die Angaben aber nicht wirklich: durch die Angabe in dem <parent>-Tag habe ich nun in jedem Modul-Projekt die Versionsnummer des Parent-POMs - und damit des gesamten Projekts - zu stehen und muss bei einem neuen Release alle Module-POMs anpassen.

Wo ist denn da die Wiederverwendung? Ich brauche zwar die Versionsnummer nicht im Modul-POM anzugeben, aber dafür die des Parent-POM, die dann vom Modul-POM wieder geerbt wird? Häh? Irgendwie fehlt mir hier ein Stück Verständnis.

Aber es ist schon spät und außerdem Wochenende - ich gehe lieber ins Bett :o) ...

Labels: ,